#include<vector>
using namespace std;
class Solution {
private:
    bool judge(const vector<int>& cur, const vector<int>& action, const vector<int>& boundary) {
        int x = cur[0] + action[0];
        int y = cur[1] + action[1];
        if (x<boundary[0] || y<boundary[1] || x>boundary[2] || y>boundary[3])
            return false;
        return true;
    }
    void update(vector<int>& boundary, int action) {
        switch (action) {
        case 0:
            boundary[0] += 1;
            break;
        case 1:
            boundary[3] -= 1;
            break;
        case 2:
            boundary[2] -= 1;
            break;
        case 3:
            boundary[1] += 1;
            break;
        }
    }
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (matrix.size() == 0) return {};
        int row = matrix.size();
        int col = matrix[0].size();
        vector<vector<int>>actions = { {0,1},{1,0},{0,-1},{-1,0} };
        vector<int>boundary = { 0,0,row - 1,col - 1 };
        vector<int>cur = { 0,0 };
        int action_id = 0;
        vector<int>res(row * col);
        int index = 0;
        while (index < res.size()) {
            res[index++] = matrix[cur[0]][cur[1]];
            if (!judge(cur, actions[action_id], boundary)) {
                update(boundary, action_id);
                action_id = (action_id + 1) % actions.size();
            }
            cur[0] += actions[action_id][0];
            cur[1] += actions[action_id][1];
        }
        return res;
    }
};

//int main() {
//    vector<vector<int>> matrix = { {1,2,3} ,{4,5,6},{7,8,9} };
//    Solution sol;
//    sol.spiralOrder(matrix);
//}